package models

import (
	"encoding/json"
	"fmt"
	"golang-blog/infrastructure/databases"
	"time"

	"gorm.io/gorm"
)

// 标签：标签之间没有层级关系

type Tag struct {
	ID int `gorm:"primary_key;auto_increment" json:"id"`

	TagName     string `gorm:"not null" json:"tag_name"`   // 标签名
	Description string `json:"descrtiption"`               // 标签描述
	CitedNum    int    `json:"cited_num" gorm:"default:1"` // 被引次数,默认从1计数
	CreatedAt   string `json:"create_at"`
	UpdatedAt   string `json:"updated_at"`
	DeletedAt   string `json:"deleted_at"`
}

func (ci *Tag) String() string {
	a, _ := json.MarshalIndent(ci, "", "  ")
	return string(a)
}
func (a *Tag) BeforeCreate(tx *gorm.DB) (err error) {
	a.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
	a.UpdatedAt = a.CreatedAt
	// a.CitedNum = a.CitedNum + 1
	return
}

// func (a *Tag) AfterCreate(tx *gorm.DB) (err error) {
// 	rawSql := fmt.Sprintf("update tags set cited_num=cited_num+1 where id=%v", a.ID)
// 	return databases.GetDB().Raw(rawSql).Error
// }

func (a *Tag) BeforeUpdate(tx *gorm.DB) (err error) {
	a.UpdatedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}
func (a *Tag) AfterUpdate(tx *gorm.DB) (err error) {
	// 判断tag是否为0
	if a.CitedNum == 0 {
		// 删除tag
		rawSql := fmt.Sprintf("delete from tags where id='%v'", a.ID)
		err = databases.GetDB().Exec(rawSql).Error
		return err
	}
	return
}
func (a *Tag) BeforeDelete(tx *gorm.DB) (err error) {
	a.DeletedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}

type Tags struct {
	wheres Tag
	Arts   []Tag
	txn    *gorm.DB
}

func NewTag(tx *gorm.DB) *Tags {
	if tx == nil {
		tx = databases.GetDB()
	}
	return &Tags{
		txn:  tx,
		Arts: make([]Tag, 1, 32),
	}
}

func (a *Tags) With(art *Tag) *Tags {
	a.Arts[0] = *art
	return a
}
func (as *Tags) Where(a *Tag) *Tags {
	as.wheres = *a
	return as
}
func (as *Tags) FirstOrCreate() (*Tag, error) {
	txn := as.txn.Debug().Where(&as.wheres).Attrs(&as.Arts)
	if err := txn.FirstOrCreate(&as.Arts[0]).Error; err != nil {
		return nil, err
	}
	return &as.Arts[0], nil
}
func (as *Tags) Create() error {
	txn := as.txn.Debug().Model(&Tag{})
	if err := txn.Create(&as.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (as *Tags) First() (*Tag, error) {
	txn := as.txn.Debug().Model(&Tag{}).Where(&as.wheres)
	if err := txn.First(&as.Arts).Error; err != nil {
		return nil, err
	}
	return &as.Arts[0], nil
}
func (a *Tags) QueryRange(page, pageSize int) (*[]Tag, int, int, error) {
	var (
		count     int64
		totalPage int
	)
	txn := a.txn.Debug().Model(&Tag{}).Where(&a.wheres)
	if err := txn.Order("id").Offset((page - 1) * pageSize).Limit(pageSize).Find(&a.Arts).Error; err != nil {
		return nil, 0, 0, err
	}
	if err := txn.Count(&count).Error; err != nil {
		return nil, 0, 0, err
	}
	if int(count)%pageSize != 0 {
		totalPage = int(count)/pageSize + 1
	} else {
		totalPage = int(count) / pageSize
	}
	return &a.Arts, len((*a).Arts), totalPage, nil
}
func (a *Tags) Update() error {
	txn := a.txn.Debug().Model(&Tag{}).Where(&a.wheres)
	if err := txn.Updates(&a.Arts[0]).Error; err != nil {
		return err
	}
	return nil
}
func (a *Tags) AddCiteNum() {
}

// 建议标签结构，不调用删除方法
func (a *Tags) Delete() error {
	txn := a.txn.Debug().Model(&Tag{}).Where(&a.wheres)
	if err := txn.Delete(&a.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (a *Tags) Counts() (int64, error) {
	var count int64
	txn := a.txn.Debug().Model(&Tag{}).Where(&a.wheres)
	if err := txn.Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

func (a *Tags) Last() (*Tag, error) {
	txn := a.txn.Debug().Model(&Tag{}).Where(&a.wheres)
	if err := txn.Last(&a.Arts).Error; err != nil {
		return nil, err
	}
	return &a.Arts[0], nil
}
